home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / KONSTR21.ZIP / konstr / SOURCE / easy.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-20  |  39.7 KB  |  1,358 lines

  1. // We need to include a few things from OS2.H
  2.  
  3. #define INCL_WIN
  4. #define INCL_GPI
  5. #define INCL_DOSMISC
  6. #define INCL_DOSPROCESS
  7. #define INCL_DEV
  8. #define INCL_SPL
  9. #define INCL_SPLDOSPRINT
  10. #define INCL_BASE
  11. #define INCL_GPIERRORS
  12.  
  13.  
  14. #include <os2.h> // Do not repeat this in your main application
  15.  
  16. #include <process.h>
  17.  
  18. // We need a few things from the C library as well.
  19.  
  20. #include "stdio.h"
  21. #include "string.h"
  22. #include "stdlib.h"
  23. #include "ctype.h"
  24.  
  25. class Answers
  26. // These are the anwers for the quick Message Dialoges below
  27. {   public :
  28.     enum { yes=MBID_YES, no=MBID_NO, abort=MBID_CANCEL };
  29. };
  30.  
  31. // For debugging:
  32. void dumplong (long n); // dump a long
  33. void dump (char *s); // dump a string
  34.  
  35. class Window;
  36. void Warning (char *s, char *title); // Will display s and beep
  37. void Message (char *s, char *title);
  38. int Question (char *s, char *title); // returns Answers::yes or Answers::no
  39. int QuestionAbort (char *s, char *title); // may return Answers::abort
  40. void Warning (char *s, char *title, Window &w);
  41. void Message (char *s, char *title, Window &w);
  42. int Question (char *s, char *title, Window &w);
  43. int QuestionAbort (char *s, char *title, Window &w);
  44. void Beep (int frequency, double seconds);
  45.  
  46. class Flag
  47. // Used for various things. Can be fixed, so that changes are
  48. // discarded.
  49. {    int F,Fix;
  50.     public :
  51.     Flag (int f=0) { F=f; Fix=0; }
  52.     // The followint should be self explaining
  53.     void set () { if (Fix) return; F=1; }
  54.     void clear () { if (Fix) return; F=0; }
  55.     void toggle () { if (Fix) return; F=!F; }
  56.     operator int () { return F; }
  57.     void fix () { Fix=1; }
  58.     void unfix () { Fix=0; }
  59.     // Make Flag=1 possible.
  60.     int operator = (int flag) { if (Fix) return flag; return F=flag; }
  61. };
  62.  
  63. class Parameter
  64. // Parameter for messages are passed in 32 Bit values.
  65. // Use this class for easy conversion from and to 32 Bit.
  66. {    MPARAM M;
  67.     public :
  68.     Parameter(long m) { M=(MPARAM)m; }
  69.     Parameter(int m1, int m2) { M=MPFROM2SHORT(m1,m2); }
  70.     Parameter(int m) { M=MPFROMSHORT(m); }
  71.     Parameter(Flag h) { M=MPFROMSHORT((int)(h)); }
  72.     Parameter(void *p) { M=(MPARAM)p; }
  73.     operator MPARAM () { return M; }
  74.     operator long () { return (long)M; }
  75.     int lower () { return SHORT1FROMMP(M); }
  76.     int higher () { return SHORT2FROMMP(M); }
  77. };
  78.  
  79. inline void start_critical ()
  80. {    DosEnterCritSec();
  81. }
  82.  
  83. inline void end_critical ()
  84. {    DosExitCritSec();
  85. }
  86.  
  87. class Time
  88. // Handle primitive time management.
  89. {    double Seconds;
  90.     public :
  91.     void set (); // ask current time
  92.     Time () { set(); } // initialize with current time
  93.     double seconds () { return Seconds; } // return seconds since UNIX 0
  94.     operator double () { set(); return Seconds; } // return current time in seconds
  95.     void sleep (double t) { DosSleep((long)(1000*t)); } // wait for t seconds
  96. };
  97.  
  98. class String
  99. // Strings are used througout EASY. They are stored on heap.
  100. {    char *P;
  101.     long Size;
  102.     public :
  103.     static long defaultsize; // set String::defaultsize=... to change it
  104.     String (); // initialized with empty default sized string
  105.     String (char *text, long size=defaultsize);
  106.         // initialized with text and size, or defaultsize of shorter
  107.     String (int id); // id from Resource
  108.         // initialized with ressource string (from STRINGTABLE)
  109.     String (String &s);
  110.     ~String (); // free heap storage
  111.     char *text () { return P; } // return content
  112.     long size () { return Size-1; } // return size
  113.     void copy (char *text, long size); // copy (get new heap space)
  114.     void copy (char *text);
  115.     void cat (char *text); // concat with the text.
  116.     char *filename (); // treat string as path and return file name
  117.     char *extension (); // return file extension
  118.     void extension (char *ext); // set file extension
  119.     int testextension (char *ext); // test, if ext is extension
  120.     void stripfilename (); // get rid of the name, make it the path
  121.     void setname (char *name); // set the name part of a path+filename
  122.     operator char * () { return P; }
  123.     operator unsigned char * () { return P; }
  124.     int todouble (double &x); // convert to double (return TRUE on success)
  125.     int tolong (long &n); // same with long
  126.     char * operator = (char *s) { copy(s); return s; }
  127.     void toupper (); // convert to upper case
  128.     int empty () { return *P==0; }
  129. };
  130.  
  131. class ConvertString : public String
  132. // Additional features: make a String of long and double
  133. {    public :
  134.     ConvertString (long n) : String("",32) { ltoa(n,*this,10); }
  135.     ConvertString (double x) : String("",32)
  136.         { sprintf((char *)(*this),"%-0.10g",x); }
  137. };
  138.  
  139. class Rectangle
  140. // A Rectangle can have negative width or height! Used for rubberboxes.
  141. {    LONG X,Y,W,H;
  142.     public :
  143.     Rectangle (LONG x, LONG y, LONG w, LONG h)
  144.     {    X=x; Y=y; W=w; H=h;
  145.     }
  146.     Rectangle ()
  147.     {    X=Y=0; W=H=1;
  148.     }
  149.     LONG x1 ()
  150.     {    if (W<0) return X+W+1;
  151.         else return X;
  152.     }
  153.     LONG x2 ()
  154.     {    if (W>0) return X+W-1;
  155.         else return X;
  156.     }
  157.     LONG y1 ()
  158.     {    if (H<0) return Y+H+1;
  159.         else return Y;
  160.     }
  161.     LONG y2 ()
  162.     {    if (H>0) return Y+H-1;
  163.         else return Y;
  164.     }
  165.     LONG x () { return X; }
  166.     LONG y () { return Y; }
  167.     LONG w () { return W; }
  168.     LONG h () { return H; }
  169.     void resize (LONG w, LONG h)
  170.     {    W=w; H=h;
  171.     }
  172.     void hrescale (double scale);
  173.     void wrescale (double scale);
  174.     // Rescale it to vertical /horizontal relation
  175.     void minsize (LONG wmin, LONG hmin);
  176. };
  177.  
  178. class Program
  179. // This class must be in every program and the instance must be named program
  180. {    HAB Hab;
  181.     HMQ Hmq;
  182.     QMSG Qmsg;
  183.     FONTMETRICS F;
  184.     public :
  185.     enum { sizeredraw=CS_SIZEREDRAW,
  186.         clipchildren=CS_CLIPCHILDREN };
  187.     Program(int style=sizeredraw|clipchildren, int size=128);
  188.     ~Program();
  189.     int getmessage();
  190.     void dispatch();
  191.     void loop(); // this is the main loop
  192.     void clear_messages(); // dispatch all open messages
  193.     HAB hab() { return Hab; }
  194.     HMQ hmq() { return Hmq; }
  195.     long sysvalue (int i)
  196.     {    return WinQuerySysValue(HWND_DESKTOP,i);
  197.     }
  198.     long width() { return sysvalue(SV_CXSCREEN); }
  199.     long height() { return sysvalue(SV_CYSCREEN); }
  200.     long wborder() { return sysvalue(SV_CXBORDER); }
  201.     long hborder() { return sysvalue(SV_CYBORDER); }
  202.     long titlebar() { return sysvalue(SV_CYTITLEBAR); }
  203.     FONTMETRICS * fontmetrics () { return &F; }
  204.     long fontheight ()
  205.     {    return F.lMaxBaselineExt;
  206.     }
  207.     long fontwidth ()
  208.     {    return F.lAveCharWidth;
  209.     }
  210. };
  211.  
  212. extern Program program; // declare this in your main module
  213.  
  214. class MsgQueue
  215. {   HMQ Handle;
  216.     public :
  217.     MsgQueue (long size=0)
  218.     {    Handle=WinCreateMsgQueue(program.hab(),size);
  219.     }
  220.     ~MsgQueue ()
  221.     {    WinDestroyMsgQueue(Handle);
  222.     }
  223.     HMQ handle () { return Handle; }
  224. };
  225.  
  226. inline void init_queue (long size=0)
  227. {    WinCreateMsgQueue(program.hab(),size);
  228. }
  229.  
  230. class PS;
  231.  
  232. const int FCF_NORMAL=
  233.     FCF_TITLEBAR|FCF_SYSMENU|FCF_SIZEBORDER|FCF_MINMAX|
  234.     FCF_SHELLPOSITION|FCF_TASKLIST|FCF_ICON;
  235. const int FCF_NORMAL_NOSIZE=
  236.     FCF_TITLEBAR|FCF_SYSMENU|FCF_BORDER|
  237.     FCF_SHELLPOSITION|FCF_TASKLIST|FCF_ICON;
  238.  
  239. class Menu;
  240.  
  241. enum clicktype
  242. // type of mouse messages
  243. {     button1,button2,button3,
  244.     button1double,button2double,button3double,
  245.     button1up,button1down,
  246.     button2up,button2down,
  247.     button3up,button3down,
  248.     mousemove
  249. };
  250.  
  251. enum pointertype
  252. // mouse pointer type
  253. {    pointer_wait=SPTR_WAIT,pointer_arrow=SPTR_ARROW,
  254.     pointer_text=SPTR_TEXT,pointer_move=SPTR_MOVE
  255. };
  256.  
  257. class Pointer
  258. // A mouse pointer from an icon.
  259. {   HPOINTER Handle;
  260.     public :
  261.     Pointer (int id)
  262.     {    Handle=WinLoadPointer(HWND_DESKTOP,0,id);
  263.     }
  264.     ~Pointer ()
  265.     {    if (Handle!=NULLHANDLE) WinDestroyPointer(Handle);
  266.     }
  267.     HPOINTER handle () { return Handle; }
  268. };
  269.  
  270. class Window
  271. // Elder class of StandardWindow.
  272. {   protected :
  273.     HWND Handle;
  274.     int Width,Height;
  275.     Flag Visible;
  276.     HPOINTER Old,New;
  277.     public :
  278.     Window ();
  279.     HWND handle () { return Handle; }
  280.     int width () { return Width; }
  281.     int height () { return Height; }
  282.     void update () { WinInvalidateRect(Handle,NULL,TRUE); }
  283.     void size (long w, long h); // call size of StandardWindow
  284.     void pos (long x, long y); // dto.
  285.     void pos (long &x, long &y, long &w, long &h);
  286.     // ask window frame position and size
  287.     void validate () { WinValidateRect(Handle,NULL,TRUE); }
  288.         // make the content valid (sometimes good after redraw)
  289.     int isvisible () { return Visible; } // yes, if not iconized
  290.     void setpointer (pointertype p); // set pointer for the window
  291.     void setpointer (Pointer &p); // set a loaded pointer.
  292.     void resetpointer (); // old pointer
  293.     void showpointer ();
  294.     void hidepointer ();
  295.     void message (int msg, Parameter mp1=0, Parameter mp2=0)
  296.     // send a message to the window
  297.     {    WinPostMsg(Handle,msg,mp1,mp2);
  298.     }
  299.     void send (int msg, Parameter mp1=0, Parameter mp2=0)
  300.     // send a message to the window
  301.     {    WinSendMsg(Handle,msg,mp1,mp2);
  302.     }
  303.     void post (int msg, Parameter mp1=0, Parameter mp2=0)
  304.     // send a message to the window
  305.     {    WinPostMsg(Handle,msg,mp1,mp2);
  306.     }
  307.     void capture (int flag=1)
  308.     // capture mouse control, needs to be released (capture(0))
  309.     {    WinSetCapture(HWND_DESKTOP,flag?Handle:NULLHANDLE);
  310.     }
  311.     void quit () { post(WM_CLOSE); }
  312.     // send quit message, best way to leave a program
  313.     void show () { WinShowWindow(Handle,TRUE); }
  314.     void hide () { WinShowWindow(Handle,FALSE); }
  315.     int hasfocus () { return WinQueryFocus(HWND_DESKTOP)==Handle; }
  316.     void setfocus () { WinSetFocus(HWND_DESKTOP,Handle); }
  317. };
  318.  
  319. class Desktop : public Window
  320. {    public :
  321.     Desktop () { Handle=HWND_DESKTOP; }
  322. };
  323.  
  324. class Scroll
  325. // scroll messages
  326. {    public :
  327.     enum {
  328.         left=SB_LINELEFT,right=SB_LINERIGHT,
  329.         pageleft=SB_PAGELEFT,pageright=SB_PAGERIGHT,
  330.         position=SB_SLIDERPOSITION,
  331.         up=SB_LINEUP,down=SB_LINEDOWN,
  332.         pageup=SB_PAGEUP,pagedown=SB_PAGEDOWN};
  333. };
  334.  
  335. class Alignment
  336. // text alignments
  337. {    public :
  338.     enum {
  339.         left=TA_LEFT,center=TA_CENTER,right=TA_RIGHT,
  340.         top=TA_TOP,middle=TA_HALF,bottom=TA_BOTTOM};
  341. };
  342.  
  343. class Keycode
  344. // key flags
  345. {    public :
  346.     enum {
  347.         up=KC_KEYUP,virtualkey=KC_VIRTUALKEY,
  348.         charkey=KC_CHAR,shift=KC_SHIFT,alt=KC_ALT,
  349.         control=KC_CTRL,lone=KC_LONEKEY,
  350.         composite=KC_COMPOSITE,down=KC_PREVDOWN,
  351.         dead=KC_DEADKEY,none=KC_NONE };
  352. };
  353.  
  354. enum {RUBBER_ZERO,RUBBER_START,RUBBER_CANCEL,RUBBER_DONE};
  355.  
  356. class WindowDialog;
  357.  
  358. class StandardWindow : public Window
  359. // This is the normal window. No subwindows are declared.
  360. // Just a drawing area.
  361. {    HWND FrameHandle;
  362.     Menu *Windowmenu; // pointer to menu
  363.     int Id; // the resource ID
  364.     int Rubber;
  365.     String Name; // the title
  366.     unsigned long Flags;
  367.     WindowDialog *Dlg;
  368.     static int msg_semaphore[4];
  369.     public :
  370.     enum {normal=FCF_NORMAL,menu=FCF_MENU,keys=FCF_ACCELTABLE,
  371.         vscrollbar=FCF_VERTSCROLL,hscrollbar=FCF_HORZSCROLL,
  372.         titlebar=FCF_TITLEBAR,sysmemu=FCF_SYSMENU,
  373.         sizeborder=FCF_SIZEBORDER,minmax=FCF_MINMAX,
  374.         min=FCF_MINBUTTON,max=FCF_MAXBUTTON,
  375.         shellposition=FCF_SHELLPOSITION,tasklist=FCF_TASKLIST,
  376.         icon=FCF_ICON,normal_nosize=FCF_NORMAL_NOSIZE,
  377.         visible=WS_VISIBLE,syncpaint=WS_SYNCPAINT,
  378.         minimized=WS_MINIMIZED,maximized=WS_MAXIMIZED,
  379.         disabled=WS_DISABLED};
  380.     // declare flags for additional controls
  381.     StandardWindow (int id,
  382.         char *name="",
  383.         unsigned long flags=FCF_NORMAL);
  384.     ~StandardWindow ();
  385.     void init (int style=visible);
  386.     void setmenu (Menu *m) { Windowmenu=m; }
  387.         // automatically called from Menu constructor
  388.     HWND framehandle () { return FrameHandle; }
  389.     void top (); // top the window
  390.     int topped (); // window topped?
  391.     int rubberbox (LONG x, LONG y, clicktype click,
  392.         Rectangle &R, LONG wmin=0, LONG hmin=0,
  393.         double wscale=0, double hscale=0);
  394.         // can be called from clicked. wmin,hmin are minimal sizes.
  395.         // either a width or a height scaling factor are optional.
  396.         // returns RUBBER_DONE etc.
  397.     virtual void redraw (PS &ps);
  398.         // the redraw routine. called by message handler
  399.     virtual void sized () {}
  400.         // called upon resize message
  401.     virtual void clicked (LONG x, LONG y, clicktype click,
  402.         int state)
  403.     {}
  404.         // called from message handler upon mouse events
  405.         // clicktype is defined above
  406.         // state defines the keyboard state
  407.     virtual int key (int flags, int code, int scan) { return 0; }
  408.         // called from message handler upon keyboard events
  409.         // flags is of Keycode class
  410.         // code is the ASCII key code, if flag is Keycode::charkey
  411.         // scan is the scan value or the virtual key, if
  412.         // falgs contains Keycode::virtualkey
  413.     void size (LONG w, LONG h);
  414.         // size the windows draw area
  415.     virtual int vscrolled (int scroll, int pos) { return 0; }
  416.         // called from message handler upon scroll messages
  417.     virtual int hscrolled (int scroll, int pos) { return 0; }
  418.     virtual void pres_changed () { update(); }
  419.         // called from message handler, if the windows default
  420.         // values change
  421.     void vscroll (int pos, int min=0, int max=100);
  422.     void hscroll (int pos, int min=0, int max=100);
  423.         // set the scroll bars
  424.     friend MRESULT EXPENTRY MainWindowProc (HWND hwnd,
  425.             unsigned long msg,MPARAM mp1, MPARAM mp2);
  426.     void title (char *s); // set window title
  427.     virtual int close () { return 1; }
  428.         // user tries to close the window
  429.         // return 0, if that is not allowed
  430.     void starttimer (double interval, int i=1)
  431.     {    WinStartTimer(program.hab(),Handle,i,(long)(interval*1000));
  432.     }
  433.         // start a window timer with the specified interval
  434.         // i is the number of the timer
  435.     void stoptimer (int i=1)
  436.     {    WinStopTimer(program.hab(),Handle,i);
  437.     }
  438.     virtual void timer (int i) {}
  439.         // called from message handler on timer events
  440.     void getframe (long &x, long &y, long &w, long &h);
  441.     void framepos (long x, long y); // Position frame.
  442.     void center (); // Center Frame Window on Screen.
  443.     void setdialog (WindowDialog &d) { Dlg=&d; }
  444.     virtual void semaphore (int n, long bits)
  445.     {} // a semaphore has occured.
  446.     void sendsemaphore (int n, long bits=1)
  447.     {    post(msg_semaphore[n-1],bits);
  448.     }
  449.     void show () { WinShowWindow(FrameHandle,TRUE); }
  450.     void hide () { WinShowWindow(FrameHandle,FALSE); }
  451. };
  452.  
  453. typedef void Menuproc ();
  454.  
  455. class Menuentry
  456. // Internal class to represent a menu entry
  457. {   int Command;
  458.     Menuproc *Proc;
  459.     Menuentry *Next;
  460.     public :
  461.     Menuentry (int command, Menuproc *proc,
  462.         Menuentry *next=NULL)
  463.     {    Command=command;
  464.         Proc=proc;
  465.         Next=next;
  466.     }
  467.     Menuentry *next () { return Next; }
  468.     void next(Menuentry *n) { Next=n; }
  469.     void call (int command) { Proc(); }
  470.     int command () { return Command; }
  471. };
  472.  
  473. class Menu
  474. // menus appear in a specified window
  475. // all entries must be entered with Menu::add
  476. {   int Command;
  477.     Menuentry *Mp;
  478.     StandardWindow *W;
  479.     public :
  480.     Menu (StandardWindow &window)
  481.     {    Mp=NULL;
  482.         W=&window;
  483.         W->setmenu(this);
  484.     }
  485.     ~Menu ();
  486.     void add (unsigned long command, Menuproc *proc)
  487.     {   Mp=new Menuentry(command,proc,Mp);
  488.     }
  489.     void remove (int id);
  490.     int call (int command);
  491.     int command () { return Command; }
  492.         // returns the ID of the last menu selection
  493.     void enable (int id, int flag);
  494.         // enable or disable menu entries
  495.     void check (int id, int flag);
  496.         // check or uncheck menu entries
  497.     HWND submenu (int id);
  498.     void additem (int id, Menuproc *proc,
  499.         char *text, int menuid, int pos=MIT_LAST);
  500.     void removeitem (int id, int menuid);
  501. };
  502.  
  503. class Rgb
  504. // Used to represent colors as unsigned long values
  505. {    unsigned long Value;
  506.     public :
  507.     Rgb (int red, int green, int blue)
  508.     {    Value=((unsigned long)red<<16)+((unsigned long)green<<8)+blue;
  509.     }
  510.     Rgb (unsigned long value=0) { Value=value; }
  511.     operator unsigned long () { return Value; }
  512. };
  513.  
  514. class Colors
  515. // The default 16 color palette
  516. {   public :
  517.     enum
  518.     {    def=CLR_DEFAULT,white=CLR_WHITE,black=CLR_BLACK,
  519.         blue=CLR_BLUE,red=CLR_RED,pink=CLR_PINK,green=CLR_GREEN,
  520.         cyan=CLR_CYAN,yellow=CLR_YELLOW,darkgray=CLR_DARKGRAY,
  521.         darkblue=CLR_DARKBLUE,darkred=CLR_DARKRED,
  522.         darkpink=CLR_DARKPINK,darkgreen=CLR_DARKGREEN,
  523.         darkcyan=CLR_DARKCYAN,brown=CLR_BROWN,palegray=CLR_PALEGRAY,
  524.         gray=CLR_PALEGRAY,neutral=CLR_NEUTRAL
  525.     };
  526. };
  527.  
  528. class Color
  529. // Color class, may be system or direct
  530. {    int D;
  531.     long V;
  532.     public :
  533.     Color (unsigned long v) : D(0),V(v) {}
  534.     Color (int r, int g, int b) : D(1),V(Rgb(r,g,b))
  535.     {}
  536.     Color () : D(0),V(CLR_DEFAULT) {}
  537.     operator unsigned long () { return V; }
  538.     int direct () { return D; }
  539. };
  540.  
  541. class Palette
  542. {   HPAL Handle;
  543.     public :
  544.     enum { pure=1, own=2 };
  545.     Palette (unsigned long a[], int n, int options=0);
  546.     ~Palette ();
  547.     HPAL handle () { return Handle; }
  548. };
  549.  
  550. class Markers
  551. // Marker types for PS::mark
  552. {    public :
  553.     enum
  554.     {    def=MARKSYM_DEFAULT,cross=MARKSYM_CROSS,plus=MARKSYM_PLUS,
  555.         diamond=MARKSYM_DIAMOND,star=MARKSYM_SIXPOINTSTAR,
  556.         square=MARKSYM_SQUARE,solidsquare=MARKSYM_SOLIDSQUARE,
  557.         soliddiamond=MARKSYM_SOLIDDIAMOND,
  558.         sixpointstar=MARKSYM_SIXPOINTSTAR,
  559.         eightpointstart=MARKSYM_EIGHTPOINTSTAR,
  560.         dot=MARKSYM_DOT,circle=MARKSYM_SMALLCIRCLE,
  561.         blank=MARKSYM_BLANK
  562.     };
  563. };
  564.  
  565. class CopyMode
  566. {      public :
  567.     enum {
  568.         copy=ROP_SRCCOPY, or=ROP_SRCPAINT, xor=ROP_SRCINVERT,
  569.     };
  570. };
  571.  
  572. class Font;
  573. class PS
  574. // The basic interface class for the graphic routines.
  575. // Has WindowPS, RedrawPS, PrinterPS, BitmapPS
  576. // and MetafilePS as children.
  577. {   POINTL P;
  578.     unsigned long Alignment;
  579.     Flag Pure;
  580.     Color C;
  581.     protected :
  582.     HPS Handle;
  583.     SIZEL S;
  584.     long X,Y;
  585.     public :
  586.     void setdefaults () // Default Initialisation
  587.     {   X=0; Y=0;
  588.         Handle=NULLHANDLE;
  589.         C=CLR_DEFAULT; Alignment=TA_LEFT;
  590.         Pure.clear();
  591.     }
  592.     PS ()
  593.     {      setdefaults();
  594.     }
  595.     PS (HPS hps)
  596.     {    setdefaults(); Handle=hps; GpiQueryPS(Handle,&S);
  597.     }
  598.     void clip (long x, long y, long w, long h); // set clipping
  599.     void offset (long x, long y) { X=x; Y=y; } // set zero offset
  600.     long xoffset () { return X; } // return offset
  601.     long yoffset () { return Y; }
  602.     HPS handle () { return Handle; } // return PS handle
  603.     void erase () { GpiErase(Handle); }
  604.     LONG width () { return S.cx; }
  605.     LONG height () { return S.cy; }
  606.     void directcolor (int pure=0);
  607.     void defaultcolors ();
  608.         // reset default palette
  609.     void color (Color color) // set draw color
  610.     {    if (C!=color)
  611.         {   if (!color.direct() && C.direct())
  612.             {    defaultcolors();
  613.             }
  614.             else if (color.direct() && !C.direct())
  615.             {    directcolor(Pure);
  616.             }
  617.             GpiSetColor(Handle,color);
  618.             C=color;
  619.         }
  620.     }
  621.     unsigned long backcolor () { return GpiQueryBackColor(Handle); }
  622.     void mix (int mode) { GpiSetMix(Handle,mode); }
  623.         // set background mix mode
  624.     void move (LONG c, LONG r, Color color=CLR_DEFAULT);
  625.         // move draw position to (c,r)
  626.     void lineto (LONG c, LONG r, Color color=CLR_DEFAULT);
  627.     void linerel (LONG w, LONG h, Color color=CLR_DEFAULT);
  628.     void point (LONG w, LONG h, Color color=CLR_DEFAULT);
  629.     void text (char *s, Color color=CLR_DEFAULT,
  630.         unsigned long alignment=TA_LEFT, unsigned long valignment=TA_BASE);
  631.     void clippedtext (char *s, long x, long y,
  632.         long x1, long y1, long x2, long y2,
  633.         Color color=CLR_DEFAULT,
  634.         unsigned long alignment=TA_LEFT, unsigned long valignment=TA_BASE);
  635.     void textbox (char *s, long &width, long &height);
  636.         // compute with and height of text
  637.     double textextend (char *s, double vx, double vy);
  638.     void framedarea (Rectangle &R, int r, Color col=CLR_DEFAULT);
  639.     void frame (Rectangle &R, int r=0, Color color=CLR_DEFAULT);
  640.     void area (Rectangle &R, int r=0, Color color=CLR_DEFAULT);
  641.     void framedarea (LONG w, LONG h, int r, Color col=CLR_DEFAULT);
  642.     void frame (LONG w, LONG h, int r=0, Color color=CLR_DEFAULT);
  643.     void area (LONG w, LONG h, int r=0, Color color=CLR_DEFAULT);
  644.         // These function draw a rectangle (filled or not,
  645.         // frame or not), r ist the corner radius for rounded
  646.         // corners.
  647.     void backarea (LONG w, LONG h);
  648.     void mark (LONG w, LONG h, unsigned long type=MARKSYM_DEFAULT,
  649.         Color color=CLR_DEFAULT);
  650.         // draw a marker
  651.     void circle (LONG c, LONG r, LONG rad, double factor,
  652.         Color color=CLR_DEFAULT);
  653.     void filledcircle (LONG c, LONG r, LONG rad, double factor,
  654.         Color color=CLR_DEFAULT, Color fillcol=CLR_DEFAULT);
  655.         // draw an ellipse
  656.     void arc (LONG c, LONG r, LONG rad, double factor,
  657.         double phi1, double phi2,
  658.         Color col=CLR_DEFAULT);
  659.     void pie (LONG c, LONG r, LONG rad, double factor,
  660.         double phi1, double phi2,
  661.         Color col=CLR_DEFAULT);
  662.     void filledpie (LONG c, LONG r, LONG rad, double factor,
  663.         double phi1, double phi2,
  664.         Color col=CLR_DEFAULT, Color fillcol=CLR_DEFAULT);
  665.         // an arc
  666.     void setfont (Font &font, int id=1);
  667.         // set the drawing font
  668.     void image (long w, long h, unsigned char *data);
  669.         // draw a B/W image
  670.     void rectcopy (PS &ps, long x, long y, long w, long h,
  671.         long x1, long y1, int mode=CopyMode::copy);
  672.         // copy a rectangle into another presentation space
  673.     void pure (int f) { Pure=f; }
  674.     int pure () { return Pure; }
  675.     void setcharbox (long x, long y);
  676. };
  677.  
  678. inline void StandardWindow::redraw (PS &ps)
  679. {    ps.erase();
  680. }
  681.  
  682. class WindowPS : public PS
  683. // A PS, which is assigned to a screen window
  684. {   Window *W;
  685.     int getps;
  686.     void set (HPS handle, Window &window)
  687.     {    W=&window;
  688.         Handle=handle;
  689.         S.cx=window.width(); S.cy=window.height();
  690.     }
  691.     public :
  692.     WindowPS (HPS handle, Window &window)
  693.     {    set(handle,window);
  694.         getps=0;
  695.     }
  696.     WindowPS (Window &window)
  697.     {    set(WinGetPS(window.handle()),window);
  698.         getps=1;
  699.     }
  700.     ~WindowPS () { if (getps) WinReleasePS(handle()); }
  701. };
  702.  
  703. class RedrawPS : public WindowPS
  704. // A PS which is generated within a redraw event
  705. // This is only used by the message handler
  706. {    public :
  707.     RedrawPS (HWND hwnd, Window &window) :
  708.         WindowPS(WinBeginPaint(hwnd,NULLHANDLE,NULL),window) {}
  709.     ~RedrawPS () { WinEndPaint(handle()); }
  710. };
  711.  
  712. class MetafilePS : public PS
  713. // A PS accosiciated to a meta file
  714. // The Metafile may be passed to the clipboard
  715. {   HMF Metafilehandle;
  716.     HDC Hdc;
  717.     public :
  718.     MetafilePS (Window &window);
  719.     MetafilePS (Window &window, long x, long y);
  720.     ~MetafilePS ();
  721.     HMF metafilehandle () { return Metafilehandle; }
  722.     void close ();
  723. };
  724.  
  725. class BitmapPS : public PS
  726. // A PS for a bitmap assigned and sized to window or
  727. // to the screen with own size.
  728. {    HDC DeviceHandle;
  729.     HBITMAP BitmapHandle;
  730.     PBITMAPINFO2 Info;
  731.     int Valid,Planes,Colorbits;
  732.     public :
  733.     BitmapPS (Window &window); // window size
  734.     BitmapPS (long w, long h);
  735.     ~BitmapPS ();
  736.     void copy (PS &ps,
  737.         long x=0, long y=0, int mode=CopyMode::copy);
  738.         // copy the bitmap to a PS
  739.     void save (char *filename);
  740.         // save the bitmap on a file
  741.     HBITMAP bitmaphandle () { return BitmapHandle; }
  742.     int valid () { return Valid; }
  743. };
  744.  
  745. class Queues
  746. // Gets all queues and selects the default one or a named one.
  747. {    unsigned long NQueues;
  748.     PRQINFO3 *Queues;
  749.     PRQINFO3 ChosenQueue;
  750.     public :
  751.     Queues (char *name="");
  752.     ~Queues () { if (Queues) delete Queues; }
  753.     unsigned long number () { return NQueues; }
  754.         // number of all queues
  755.     PRQINFO3 *chosen () { return &ChosenQueue; }
  756.         // the default or named queue
  757.     PRQINFO3 *all ();
  758.         // return all queues (number())
  759. };
  760.  
  761. class PrinterPS : public PS
  762. // A PS for the printer
  763. {   HDC HandlePrinter;
  764.     DEVOPENSTRUC Dos;
  765.     String Myname;
  766.     PRQINFO3 Queue;
  767.     public :
  768.     Flag Valid,Open;
  769.     PrinterPS (char *name="Print", int op=1);
  770.         // name is the output name, op=0 means: do not open
  771.         // This will take the default queue
  772.     PrinterPS (Queues &q, char *name="Print", int op=1);
  773.         // The prefered way.
  774.         // Declare a qeueu instance and pass it to the PrinterPS
  775.     ~PrinterPS () { if (Open) close(); }
  776.     char *queuename () { return Dos.pszLogAddress; }
  777.     char *drivername () { return Dos.pszDriverName; }
  778.     void open (); // open (normally at construction time)
  779.     void close (); // close (called from destructor)
  780.     void newpage (); // start a new print page
  781. };
  782.  
  783. class Bitmap
  784. // for bitmaps from the ressource
  785. // used by ValueSetItems in dialogs
  786. {    HBITMAP Handle;
  787.     HDC DeviceHandle;
  788.     HPS PsHandle;
  789.     SIZEL S;
  790.     public :
  791.     Bitmap (int id, int width=0, int height=0);
  792.         // id is the ressource ID
  793.     ~Bitmap ();
  794.     HBITMAP handle () { return Handle; }
  795. };
  796.  
  797. class Help
  798. // help interface
  799. // the program should have a *.HLP file associated to it
  800. // you need to declare a HELPTABLE and at least one HELPSUBTABLE
  801. // HELPTABLE ID_Help
  802. //        BEGIN
  803. //         HELPITEM ID_Window,ID_Helpsubtable,ID_GeneralHelpPage
  804. //      END
  805. // ID_GeneralHelpPage is an ID in your IPF file
  806. // HELPSUBTABLE ID_Helpsubtable
  807. //        BEGIN
  808. //        END
  809. {   HWND Handle;
  810.     Help *H;
  811.     Flag Valid;
  812.     public :
  813.     Help (StandardWindow &window,
  814.         int id, char *filename, char *title="");
  815.         // id is the help tables id
  816.     void Help::general (void) // display general help page
  817.     {    if (Valid) WinSendMsg(Handle,HM_EXT_HELP,NULL,NULL);
  818.     }
  819.     void Help::index (void) // display help index
  820.     {    if (Valid) WinSendMsg(Handle,HM_HELP_INDEX,NULL,NULL);
  821.     }
  822.     void Help::content (void) // display content
  823.     {   if (Valid) WinSendMsg(Handle,HM_HELP_CONTENTS,NULL,NULL);
  824.     }
  825.     void Help::display (int id) // display specific page
  826.     {    if (Valid) WinSendMsg(Handle,HM_DISPLAY_HELP,
  827.             MPFROMSHORT(id),HM_RESOURCEID);
  828.     }
  829.     int valid () { return Valid; } // help file found?
  830. };
  831.  
  832. class Thread
  833. // a class to start a a thread
  834. // the instance will call a function of type "int f (Parameter)"
  835. // this allows a Parameter to be passed to the function
  836. // the function returns an exit code
  837. // You need to declare a separate instance of Thread for each thread
  838. {    int (*F) (Parameter);
  839.     TID Tid;
  840.     int Started,Expected;
  841.     long Stacksize;
  842.     Parameter P;
  843.     HMQ Hmq;
  844.     public :
  845.     Thread (int (*f) (Parameter), long stacksize=4096) :
  846.         P(0)
  847.     {    F=f;
  848.         Started=0; Stacksize=stacksize;
  849.         Expected=0;
  850.     }
  851.     void start (Parameter p=0); // call the function
  852.     void stop (); // stop the thread destructively
  853.     void suspend (); // suspend it
  854.     void resume (); // resume it after suspension
  855.     void wait ();
  856.         // tell the function that you wait for it
  857.         // the function may call expected() to check this
  858.     int expected () { return Expected; }
  859.     Parameter p () { return P; }
  860.     int call () { return F(P); }
  861.     int started () { return Started; }
  862.         // was the thread already started?
  863.     void finished () { Started=0; }
  864. };
  865.  
  866. class Dialogitem;
  867. class Dialog
  868. // class to display and handle a dialog
  869. // create the dialog in your ressource script
  870. // use the Dialogitem class to implement the various controls
  871. // many controls are already defined here, but you may wish
  872. // to add others
  873. // the dialog knows about the controls added to it and calls
  874. // their handlers on init and exit and change
  875. {    String S;
  876.     Help *H;
  877.     int Hid;
  878.     void init (Window &window, int id);
  879.     Dialog *Next;
  880.     protected :
  881.     int Id;
  882.     HWND Handle;
  883.     Window *W;
  884.     protected :
  885.     int Result;
  886.     Dialogitem *Items;
  887.     public :    enum { ok=DID_OK,cancel=DID_CANCEL }; // return values
  888.     Dialog (Window &window, int id); // id from ressource
  889.     Dialog (Window &window, int id, Help &h, int hid);
  890.         // add help to a dialog (hid is the help page)
  891.     Dialogitem *entry (Dialogitem *item);
  892.     virtual void carryout (); // display the dialog and start it
  893.     virtual void start () {}
  894.         // you may do additional initializations
  895.     virtual void stop () {}
  896.         // you may add additional exit things
  897.     virtual int handler (int command) { return 0; }
  898.         // you may add a handler, which returns 0 on any
  899.         // command it could handle
  900.     int result () { return Result; }
  901.     char *gettext (int id, char *text, long size=String::defaultsize);
  902.     char *gettext (int id);
  903.     void settext (int id, char *text);
  904.     MRESULT message (int id, int msg,
  905.         Parameter mp1=NULL, Parameter mp2=NULL);
  906.     HWND handle () { return Handle; }
  907.     friend MRESULT EXPENTRY dialogproc (HWND hwnd, unsigned long msg,
  908.         MPARAM mp1, MPARAM mp2);
  909.     void finish ()
  910.     {    WinSendMsg(Handle,WM_COMMAND,MPARAM(DID_OK),0);
  911.     }
  912.     virtual int key (int flags, int code, int scan) { return 0; }
  913.     Window *w () { return W; }
  914.     virtual int close () { return 1; }
  915.     void getframe (LONG &x, LONG &y, LONG &w, LONG &h);
  916.     void move (LONG x, LONG y);
  917.     void framepos (LONG x, LONG y) { move(x,y); }
  918.     void enable (int id, int flag=1)
  919.     {    WinEnableWindow(WinWindowFromID(Handle,id),flag);
  920.     }
  921. };
  922.  
  923. class DialogPanel : public Dialog
  924. // A Dialog, which remains open, until it is finished
  925. {    public :
  926.     DialogPanel (Window &window, int id)
  927.      : Dialog(window,id) {}
  928.     DialogPanel (Window &window, int id, Help &h, int hid)
  929.      : Dialog(window,id,h,hid) {}
  930.     virtual void carryout ();
  931.     virtual void show () { carryout(); }
  932.     virtual int close () { return 0; }
  933. };
  934.  
  935. class WindowDialog : public Dialog
  936. {   int Ids;
  937.     public :
  938.     WindowDialog (StandardWindow &w);
  939.     int newid () { return ++Ids; }
  940.     int command (Parameter p1, Parameter p2);
  941. };
  942.  
  943. class Dialogitem
  944. // this is a control item in a dialog
  945. // note: if the dialog is declared globally, then all its items
  946. // must be declared globally too.
  947. {    Dialogitem *Next;
  948.     protected :
  949.     int Id;
  950.     Dialog *D;
  951.     public :
  952.     Dialogitem (int id, Dialog &dialog);
  953.         // id is the ressource ID for the control
  954.     Dialogitem *next () { return Next; }
  955.     int id () { return Id; }
  956.     virtual void init () {} // called on dialog start
  957.     virtual void exit () {} // called on dialog end
  958.     virtual void command (Parameter mp1, Parameter mp2) {}
  959.         // called, if a command refers to the item ID
  960.     virtual void notify () {}
  961.         // some child items call this, if the control
  962.         // changes its value
  963.     void finish () { D->finish(); }
  964.         // aborts the dialog
  965.     void pos (long x, long y);
  966.         // position dialog element
  967.     void size (long w, long h);
  968.         // size dialog element
  969.     void sizepos (long x, long y, long w, long h);
  970.         // size and position dialog element
  971.     HWND handle () { return WinWindowFromID(D->handle(),Id); }
  972.     void setfocus () { WinSetFocus(HWND_DESKTOP,handle()); }
  973.     int hasfocus () { return WinQueryFocus(HWND_DESKTOP)==handle(); }
  974. };
  975.  
  976. class ButtonItem : public Dialogitem
  977. // A Button, normally handled by a Dialog::handler()
  978. {    Flag Pressed;
  979.     public :
  980.     enum { def=BS_DEFAULT, autosize=BS_AUTOSIZE,
  981.         nofocus=BS_NOPOINTERFOCUS, noborder=BS_NOBORDER,
  982.         help=BS_HELP, icon=BS_ICON };
  983.     ButtonItem (int id, Dialog &dialog)
  984.         : Dialogitem(id,dialog),Pressed(0) {}
  985.     ButtonItem (WindowDialog &d,
  986.         long x, long y, long w, long h, char *text,
  987.         int style=0);
  988.     ButtonItem (WindowDialog &d,
  989.         long x, long y, long w, long h, int iconid,
  990.         int style=icon);
  991.     virtual void command (Parameter mp1, Parameter mp2)
  992.     {   Pressed.set();
  993.         notify();
  994.     }
  995.     int flag () { return Pressed; }
  996.     void click () { D->message(id(),BM_CLICK); }
  997. };
  998.  
  999. class CheckItem : public Dialogitem
  1000. // A check box control item
  1001. // You may declare it globally and use reinit(f) to
  1002. // set its value
  1003. {    int F;
  1004.     public :
  1005.     CheckItem (int id, Dialog &dialog, int flag=0)
  1006.         : Dialogitem(id,dialog),F(flag) {}
  1007.         // flag==TRUE checks the item initially
  1008.     virtual void init ();
  1009.     virtual void exit ();
  1010.     virtual void command (Parameter mp1, Parameter mp2);
  1011.     void set (int f) { F=f; }
  1012.     void reinit (int f) { set(f); init(); }
  1013.     int flag () { return F; }
  1014.     operator int () { return F; } // return check or not check
  1015. };
  1016.  
  1017.  
  1018. class RadioItem;
  1019. class RadioButton : public Dialogitem
  1020. {    int N;
  1021.     Flag F;
  1022.     RadioItem *R;
  1023.     public :
  1024.     RadioButton (int id, Dialog &dialog, int flag,
  1025.         RadioItem &r, int n) :
  1026.             Dialogitem(id,dialog),N(n),R(&r),F(flag) {}
  1027.     virtual void command (Parameter mp1, Parameter mp2);
  1028.     virtual void init ();
  1029. };
  1030.  
  1031. class RadioItem
  1032. // A radio box item
  1033. // it is initialized with the IDs of all its buttons
  1034. {    int I,N,*Ids;
  1035.     RadioButton **Rb;
  1036.     Dialog *D;
  1037.     public :
  1038.     RadioItem (int *ids, int n, Dialog &dialog, int i=1);
  1039.     ~RadioItem ();
  1040.     operator int () { return I; } // index of selection
  1041.     void sel (int sel);
  1042.     virtual void notify () {}
  1043. };
  1044.  
  1045.  
  1046. class StringItem : public Dialogitem
  1047. // An input line control box
  1048. {   String S;
  1049.     int Length;
  1050.     Flag Readonly,Changed;
  1051.     public :
  1052.     enum { left=ES_LEFT,right=ES_RIGHT,center=ES_CENTER,
  1053.         autoscroll=ES_AUTOSCROLL,readonlyflag=ES_READONLY,
  1054.         hidden=ES_UNREADABLE,autotab=ES_AUTOTAB,
  1055.         margin=ES_MARGIN,autosize=ES_AUTOSIZE };
  1056.     StringItem (int id, Dialog &dialog, char *string,
  1057.             int length=64)
  1058.         : Dialogitem(id,dialog),S(string),Length(length),
  1059.             Changed(0)
  1060.     {}
  1061.         // initialize with any string
  1062.     StringItem (WindowDialog &dialog,
  1063.         long x, long y, long w, long h,
  1064.         char *string, int length=64,
  1065.         int style=left|autoscroll|margin);
  1066.     virtual void exit ();
  1067.     int changed ();
  1068.     virtual void init ();
  1069.     void set (char *text) { S.copy(text); }
  1070.     void reinit (char *text) { set(text); init(); }
  1071.     void limit (int length); // extend limit
  1072.     void readonly (int flag=1) { Readonly=flag; }
  1073.         // make the control read only
  1074.     char *text () { exit(); return S; }
  1075.     operator char * () { exit(); return S; }
  1076. };
  1077.  
  1078. class DoubleItem : public Dialogitem
  1079. // a input line which is interpreted as a double value
  1080. {   double X;
  1081.     String S;
  1082.     Flag Readonly;
  1083.     public :
  1084.     DoubleItem (int id, Dialog &dialog, double x)
  1085.         : Dialogitem(id,dialog),S("",64) { X=x; }
  1086.     virtual void init ();
  1087.     virtual void exit ();
  1088.     void set (double x) { X=x; }
  1089.     void reinit (double x) { set(x); init(); }
  1090.     void readonly (int flag=1) { Readonly=flag; }
  1091.     double value () { exit(); return X; }
  1092.     operator double () { return X; }
  1093. };
  1094.  
  1095.  
  1096. class LongItem : public Dialogitem
  1097. // same as double item for long values
  1098. {   long N;
  1099.     String S;
  1100.     Flag Readonly;
  1101.     public :
  1102.     LongItem (int id, Dialog &dialog, long n)
  1103.         : Dialogitem(id,dialog),S("",64) { N=n; }
  1104.     virtual void init ();
  1105.     virtual void exit ();
  1106.     void set (long n) { N=n; }
  1107.     void reinit (long n) { set(n); init(); }
  1108.     void readonly (int flag=1) { Readonly=flag; }
  1109.     long value () { exit(); return N; }
  1110.     operator long () { return N; }
  1111.     operator char * () { return S; }
  1112. };
  1113.  
  1114. class SpinItem : public Dialogitem
  1115. // A spin control box
  1116. {   long N,Lower,Upper;
  1117.     String S;
  1118.     public :
  1119.     SpinItem (int id, Dialog &dialog, long n,
  1120.         long lower, long upper)
  1121.         : Dialogitem(id,dialog),S("",64)
  1122.     {    N=n; Lower=lower; Upper=upper;
  1123.     }
  1124.     // you may specify lower and upper limits
  1125.     virtual void init ();
  1126.     virtual void exit ();
  1127.     void set (long n, long lower, long upper)
  1128.     {    N=n; Lower=lower; Upper=upper; }
  1129.     void reinit (long n, long lower, long upper)
  1130.     {    set(n,lower,upper); init();
  1131.     }
  1132.     void set (long n) { N=n; }
  1133.     void reinit (long n) { set(n); init(); }
  1134.     operator long () { return N; }
  1135. };
  1136.  
  1137.  
  1138. class SliderItem : public Dialogitem
  1139. // a slider control box
  1140. // you probably want to modify init to set ticks and labels
  1141. // just subclass it with new virtual init
  1142. // call SliderItem::init() from there
  1143. {   long N;
  1144.     String S;
  1145.     public :
  1146.     SliderItem (int id, Dialog &dialog, long n)
  1147.         : Dialogitem(id,dialog),S("",64)
  1148.     {    N=n;
  1149.     }
  1150.     virtual void init ();
  1151.     virtual void exit ();
  1152.     void set (long n)
  1153.     {    N=n; }
  1154.     void reinit (long n)
  1155.     {    set(n); init();
  1156.     }
  1157.     void tick (int n, int size=3);
  1158.     void label (int n, char *text);
  1159.     long value () { exit(); return N; }
  1160.     operator long () { return N; }
  1161.     virtual void command (Parameter mp1, Parameter mp2);
  1162.     virtual void changing (long pos) {}
  1163. };
  1164.  
  1165.  
  1166. class ValuesetItem : public Dialogitem
  1167. // a value set control box (for colors or bitmap choices)
  1168. // again, you must subclass it to modify init() to enter
  1169. // your specific value items
  1170. {    int Col,Row;
  1171.     public :
  1172.     ValuesetItem (int id, Dialog &dialog, int r=1, int c=1)
  1173.         : Dialogitem(id,dialog),Col(c),Row(r) {}
  1174.     void select (int row, int col);
  1175.     void setbitmap (int row, int col, Bitmap &b);
  1176.         // set a field to a bitmap
  1177.     void setcolor (int row, int col, unsigned long color);
  1178.         // set a field to a color
  1179.     virtual void init () { select(Row,Col); }
  1180.     virtual void exit ();
  1181.     virtual void command (Parameter mp1, Parameter mp2);
  1182.         // messages are passed to this (for reactions to changes)
  1183.     int col () { return Col; } // get selected column
  1184.     int row () { return Row; } // get selected row
  1185. };
  1186.  
  1187. class ListItem : public Dialogitem
  1188. // list control box
  1189. // you must subclass to define an init, which inserts the list entries
  1190. {   int Selection;
  1191.     public :
  1192.     ListItem (int id, Dialog &dialog)
  1193.         : Dialogitem(id,dialog) {}
  1194.     void select (int sel);
  1195.     virtual void init () { select(0); }
  1196.     virtual void exit ();
  1197.     virtual void command (Parameter mp1, Parameter mp2);
  1198.     void insert (char *text); // insert a list entry
  1199.     operator int () { return Selection; }
  1200. };
  1201.  
  1202. class MultilineItem : public Dialogitem
  1203. // multiline control box (a small editor)
  1204. // no need to subclass this time
  1205. {   String S;
  1206.     Flag Readonly,Changed;
  1207.     public :
  1208.     enum { border=MLS_BORDER,readonlystyle=MLS_READONLY,
  1209.         wrap=MLS_WORDWRAP,hscroll=MLS_HSCROLL,
  1210.         vscroll=MLS_VSCROLL,notab=MLS_IGNORETAB,
  1211.         noundo=MLS_DISABLEUNDO };
  1212.     MultilineItem (int id, Dialog &dialog, char *string,
  1213.             long length=1024)
  1214.         : Dialogitem(id,dialog),S(string,length),Changed(0)
  1215.     {}
  1216.     MultilineItem (WindowDialog &dialog,
  1217.         long x, long y, long w, long h,
  1218.         char *string="",long length=1024,
  1219.         int style=wrap|border);
  1220.     int changed ();
  1221.     virtual void init ();
  1222.     virtual void exit ();
  1223.     void set (char *text) { S.copy(text); }
  1224.     void reinit (char *text) { set(text); init(); }
  1225.     void limit (int length);
  1226.     void readonly (int flag=1) { Readonly=flag; }
  1227.     char * text () { exit(); return S; }
  1228.     operator char * () { exit(); return S; }
  1229. };
  1230.  
  1231. class FileSelector
  1232. // a file selector
  1233. // should be static, so that path information is not lost
  1234. {    int Freturn;
  1235.     Window *W;
  1236.     FILEDLG Fd;
  1237.     String Filter,Title,Ok;
  1238.     public :
  1239.     FileSelector(Window &window,
  1240.         char *filter, int saving,
  1241.         char *title="", char *ok=0);
  1242.         // example ...(window,"*.c",1,"Save C text","Save")
  1243.         // saving==FALSE means a load dialog
  1244.     char *select ();
  1245.     char *select (char *name);
  1246.         // start the dialog
  1247. };
  1248.  
  1249. class FontSelector
  1250. // a font selector
  1251. // after selection, the instance can be used to create a font
  1252. // with the Font class
  1253. {   FONTDLG Fd;
  1254.     String Facename;
  1255.     int Codepage,Type,Result;
  1256.     double Pointsize;
  1257.     public :
  1258.     enum { screen=1, printer=2 };
  1259.     FontSelector (int type=screen,
  1260.         char *name="", double pointsize=10, int codepage=0)
  1261.         : Type(type),Facename(name,66),Pointsize(pointsize),
  1262.             Codepage(codepage),Result(DID_CANCEL) {}
  1263.     int select (Window &window);
  1264.     FATTRS *fat () { return &Fd.fAttrs; }
  1265.     FONTDLG *fd () { return &Fd; }
  1266.     operator int () { return Result; }
  1267. };
  1268.  
  1269.  
  1270. class Fonts
  1271. // A list of all fonts
  1272. {    long Count;
  1273.     FONTMETRICS *AllFonts;
  1274.     public :
  1275.     Fonts (PS &ps);
  1276.     ~Fonts ();
  1277.     long count () { return Count; }
  1278.     FONTMETRICS *fonts () { return AllFonts; }
  1279. };
  1280.  
  1281. class Font
  1282. // can be initialized by a font selector
  1283. // the window font can be set to any instance of Font
  1284. {    FATTRS Fat;
  1285.     public :
  1286.     enum { italic=FATTR_SEL_ITALIC,
  1287.         underscore=FATTR_SEL_UNDERSCORE,
  1288.         strikeout=FATTR_SEL_STRIKEOUT,
  1289.         bold=FATTR_SEL_BOLD,
  1290.         hollow=FATTR_SEL_OUTLINE,
  1291.         kerning=FATTR_TYPE_KERNING,
  1292.         nomix=FATTR_FONTUSE_NOMIX,
  1293.         outline=FATTR_FONTUSE_OUTLINE,
  1294.         transformable=FATTR_FONTUSE_TRANSFORMABLE };
  1295.     Font (FontSelector &fs);
  1296.     Font (char *name, long height, long width=0,
  1297.         long attributes=nomix, long type=0, int codepage=850);
  1298.     Font (long id, char *name, long fontparams=0);
  1299.     FATTRS *fat () { return &Fat; }
  1300.     char *name () { return Fat.szFacename; }
  1301.     void set (long attribute) { Fat.fsSelection=attribute; }
  1302.     long width () { return Fat.lAveCharWidth; }
  1303.     long height () { return Fat.lMaxBaselineExt; }
  1304.     long id () { return Fat.lMatch; }
  1305.     long params () { return Fat.fsSelection; }
  1306. };
  1307.  
  1308. class FontMetrics
  1309. {    FONTMETRICS Fm;
  1310.     public :
  1311.     FontMetrics (PS &ps)
  1312.     {    GpiQueryFontMetrics(ps.handle(),
  1313.             sizeof(FONTMETRICS),&Fm);
  1314.     }
  1315.     long id () { return Fm.lMatch; }
  1316.     FONTMETRICS * fm () { return &Fm; }
  1317. };
  1318.  
  1319. class Profile
  1320. // system or user profiles are used to personalize an application
  1321. {    int P;
  1322.     String S,H;
  1323.     public :
  1324.     enum { user=HINI_USERPROFILE,system=HINI_SYSTEMPROFILE };
  1325.     Profile (char *prog, int p=user) : P(p),S(prog),H("") {}
  1326.         // prog is the programs profile name
  1327.     void write (char *k, void *p, unsigned long size)
  1328.     // write binary data to the profile (k is the key)
  1329.     {    PrfWriteProfileData(P,(char *)S,k,p,size);
  1330.     }
  1331.     void writestring (char *k, char *i);
  1332.     void writedouble (char *k, double x);
  1333.     void writelong (char *k, long x);
  1334.     void writeint (char *k, int x);
  1335.         // specific key formats
  1336.     int read (char *k, void *p, unsigned long size)
  1337.     {    if (PrfQueryProfileData(P,(char *)S,k,p,&size))
  1338.             return size;
  1339.         else return 0;
  1340.     }
  1341.     // read binary data from the profile
  1342.     char *readstring (char *k, char *d="",
  1343.         long size=String::defaultsize);
  1344.     double readdouble (char *k, double x=0);
  1345.     long readlong (char *k, long x=0);
  1346.     int readint (char *k, int x=0);
  1347.     void clear () { writestring(0,0); }
  1348.     void clear (char *k) { writestring(k,0); }
  1349. };
  1350.  
  1351. class Clipboard
  1352. // clipboard interface
  1353. {    public :
  1354.     void copy (MetafilePS &meta);
  1355.         // copy a meta file to the clipboard
  1356. };
  1357.  
  1358.